//
//  NSPredicateTest.m
//  RegexDemo
//
//  Created by 周文成 on 2018/1/4.
//  Copyright © 2018年 C-LOVE. All rights reserved.
//

#import "NSPredicateTest.h"

@implementation NSPredicateTest



+ (void)test {

    [self checkSpecialCharacter];
    [self nameLike];
    [self in10And20];
    [self stringBeginWith];
    [self stringEndWith];
    [self stringContains];
    [self stringLike];
    [self stringMatches];
    [self notNotEqual100];
    [self orEqual90OrEqual100];
    [self andGreater90AndLess100];
    [self numberGreaterOrEqualThan100];
    [self numberLessOrEqualThan100];
    [self numberGreaterThan100];
    [self numberGreaterThan100];
    [self numberNotEqual100];
    [self numberBetween100T0200];
    [self isEqualStringis123];
    [self isEqual10]; 
}


#pragma mark- === 检测特殊符号 ====
+ (void)checkSpecialCharacter {
    NSString *s1 = @"!";
    NSString *s2 = @"a";
    NSString *s3 = @"@";
    NSString *regex =  @"[`~!@#$^&*()=|{}':;',\\[\\].<>/?~！@#￥……&*（）——|{}【】‘；：”“'。，、？]";
    NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    
    NSLog(@"%@ %@",s1, [pre evaluateWithObject:s1]?@"存在特殊符":@"不存在特殊符");
    NSLog(@"%@ %@",s2, [pre evaluateWithObject:s2]?@"存在特殊符":@"不存在特殊符");
    NSLog(@"%@ %@",s3, [pre evaluateWithObject:s3]?@"存在特殊符":@"不存在特殊符");
    
}

#pragma mark- === 对象处理 ====

+ (void)nameLike {
    Person *p1 = [Person personWithName:@"XCWZ" age:18];
    NSPredicate *pre = [NSPredicate predicateWithFormat:@"name LIKE '*XC*'"];
    NSLog(@"%@", [pre evaluateWithObject:p1] ? @"name包括 XC": @"name不包括 XC");
}



#pragma mark- ==== 集合运算符 ====
/**
 * ANY、SOME：集合中任意一个元素满足条件，就返回YES。
 * ALL：集合中所有元素都满足条件，才返回YES。
 * NONE：集合中没有任何元素满足条件就返回YES。如:NONE person.age < 18，表示person集合中所有元素的age>=18时，才返回YES。
 * IN：等价于SQL语句中的IN运算符，只有当左边表达式或值出现在右边的集合中才会返回YES。我们通过一个例子来看一下
 */


/** NONE */
+ (void)none18 {
    // 暂时不知道
}


/** IN */
+ (void)in10And20 {
    NSArray *array = @[@"10", @"20", @"30", @"40"];
    NSPredicate *pre = [NSPredicate predicateWithFormat:@"NOT (SELF IN %@)", @[@"10", @"20"]];
//    NSPredicate *pre = [NSPredicate predicateWithFormat:@"NOT (SELF IN (10, 20))"]; //这样不行
    NSLog(@"%@", [array filteredArrayUsingPredicate:pre]);
}

#pragma mark- ==== 字符串比较运算符 ====
/**
 * BEGINSWITH：检查某个字符串是否以指定的字符串开头（如判断字符串是否以a开头：BEGINSWITH 'a'）
 * ENDSWITH：检查某个字符串是否以指定的字符串结尾
 * CONTAINS：检查某个字符串是否包含指定的字符串
 * LIKE：检查某个字符串是否匹配指定的字符串模板。其之后可以跟?代表一个字符和*代表任意多个字符两个通配符。比如"name LIKE '*ac*'"，这表示name的值中包含ac则返回YES；"name LIKE '?ac*'"，表示name的第2、3个字符为ac时返回YES。
 * MATCHES：检查某个字符串是否匹配指定的正则表达式。虽然正则表达式的执行效率是最低的，但其功能是最强大的，也是我们最常用的。
 */

/** BEGINSWITH */
+ (void)stringBeginWith {
    NSString *string1 = @"abcd";
    NSString *string2 = @"sddvdv";
    NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF ENDSWITH 'ab'"];
    NSLog(@"string1:%@ %@", string1, [pre evaluateWithObject:string1]? @"以ab开始":@"不以ab开始");
    NSLog(@"string2:%@ %@", string2, [pre evaluateWithObject:string2]? @"以ab开始":@"不以ab开始");
}


/** ENDSWITH */
+ (void)stringEndWith {
    NSString *string1 = @"abcd";
    NSString *string2 = @"sddvdv";
    NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF ENDSWITH 'bc'"];
    NSLog(@"string1:%@ %@", string1, [pre evaluateWithObject:string1]? @"以bc结尾":@"不以bc结尾");
    NSLog(@"string2:%@ %@", string2, [pre evaluateWithObject:string2]? @"以bc结尾":@"不以bc结尾");
}

/** CONTAINS */
+ (void)stringContains {
    NSString *string1 = @"abcd";
    NSString *string2 = @"sddvdv";
    NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF CONTAINS 'abc'"];
    NSLog(@"string1:%@ %@", string1, [pre evaluateWithObject:string1]? @"包含abc":@"不包含abc");
    NSLog(@"string2:%@ %@", string2, [pre evaluateWithObject:string2]? @"包含abc":@"不包含abc");
}

/** LIKE  */
+ (void)stringLike {
    NSString *string1 = @"abcd";
    NSString *string2 = @"18566699877";
    NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF Like '*abc*'"];
    NSLog(@"string1:%@ %@", string1, [pre evaluateWithObject:string1]? @"包含abc":@"不包含abc");
    NSLog(@"string2:%@ %@", string2, [pre evaluateWithObject:string2]? @"包含abc":@"不包含abc");
}

/** MATCHES 用于正则表达式 */
+ (void)stringMatches {
    NSString *string1 = @"9999999";
    NSString *string2 = @"18566699877";
    NSString *regex = @"^[0-9]{11}";
    NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    NSLog(@"string1:%@ %@", string1, [pre evaluateWithObject:string1]? @"是11位数字":@"不是11位数字");
    NSLog(@"string2:%@ %@", string2, [pre evaluateWithObject:string2]? @"是11位数字":@"不是11位数字");
}


#pragma mark- ==== 关系运算符 ====
/**
 * AND&& 逻辑与，要求两个表达式的值都为YES时，结果才为YES
 * OR  || 逻辑或，要求其中一个表达式为YES时，结果就是YES
 * NOT !  逻辑非，对原有的表达式取反
 */


/** AND && 逻辑与，要求两个表达式的值都为YES时，结果才为YES */
+ (void)andGreater90AndLess100 {
    NSNumber *number1 = @98;
    NSNumber *number2 = @100;
    NSNumber *number3 = @102;
    NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF > 90 && SELF < 100"];
    NSLog(@"number1:%@ %@", number1, [pre evaluateWithObject:number1]? @"90到100间":@"大于90且小于100");
    NSLog(@"number2:%@ %@", number2, [pre evaluateWithObject:number2]? @"90到100间":@"大于90且小于100");
    NSLog(@"number3:%@ %@", number3, [pre evaluateWithObject:number3]? @"90到100间":@"大于90且小于100");
}

/** OR || 逻辑或，要求其中一个表达式为YES时，结果就是YES */
+ (void)orEqual90OrEqual100 {
    NSNumber *number1 = @90;
    NSNumber *number2 = @100;
    NSNumber *number3 = @102;
    NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF == 90 OR SELF = 100"];
    NSLog(@"number1:%@ %@", number1, [pre evaluateWithObject:number1]? @"等于90或等于100":@"不是等于90或等于100");
    NSLog(@"number2:%@ %@", number2, [pre evaluateWithObject:number2]? @"等于90或等于100":@"不是等于90或等于100");
    NSLog(@"number3:%@ %@", number3, [pre evaluateWithObject:number3]? @"等于90或等于100":@"不是等于90或等于100");
}

/** NOT ! 逻辑非，对原有的表达式取反 */
+ (void)notNotEqual100 {
    NSNumber *number1 = @90;
    NSNumber *number2 = @100;
    NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF != 100"];
    NSLog(@"number1:%@ %@", number1, [pre evaluateWithObject:number1]? @"不等于100":@"等于100");
    NSLog(@"number2:%@ %@", number2, [pre evaluateWithObject:number2]? @"不等于100":@"等于100");
}


#pragma mark- ==== 比较运算符 ====

/**
 * >=，=> ：判断左边表达式的值是否大于或等于右边表达式的值
 * <=，=< ：判断右边表达式的值是否小于或等于右边表达式的值
 * > ：判断左边表达式的值是否大于右边表达式的值
 * < ：判断左边表达式的值是否小于右边表达式的值
 * !=、<> ：判断两个表达式是否不相等
 * BETWEEN ：BETWEEN表达式必须满足表达式 BETWEEN {下限，上限}的格式，要求该表达式必须大于或等于下限，并小于或等于上限
 */

/** >=，=> 判断左边表达式的值是否大于或等于右边表达式的值 */
+ (void)numberGreaterOrEqualThan100 {
    NSNumber *number1 = @98;
    NSNumber *number2 = @100;
    NSPredicate *pre1 = [NSPredicate predicateWithFormat:@"SELF >= 100"];
    NSPredicate *pre2 = [NSPredicate predicateWithFormat:@"SELF => 100"];
    NSLog(@"number1:%@ %@", number1, [pre1 evaluateWithObject:number1]? @"大于等于100":@"小于100");
    NSLog(@"number2:%@ %@", number2, [pre2 evaluateWithObject:number2]? @"大于等于100":@"小于100");
}

/** <=，=< 判断右边表达式的值是否小于或等于右边表达式的值 */
+ (void)numberLessOrEqualThan100 {
    NSNumber *number1 = @200;
    NSNumber *number2 = @100;
    NSPredicate *pre1 = [NSPredicate predicateWithFormat:@"SELF <= 100"];
    NSPredicate *pre2 = [NSPredicate predicateWithFormat:@"SELF =< 100"];
    NSLog(@"number1:%@ %@", number1, [pre1 evaluateWithObject:number1]? @"小于等于100":@"大于100");
    NSLog(@"number2:%@ %@", number2, [pre2 evaluateWithObject:number2]? @"小于等于100":@"大于100");
}

/** > 判断左边表达式的值是否大于右边表达式的值 */
+ (void)numberGreaterThan100 {
    NSNumber *number1 = @200;
    NSNumber *number2 = @100;
    NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF > 100"];
    NSLog(@"number1:%@ %@", number1, [pre evaluateWithObject:number1]? @"大于100":@"小于或等于100");
    NSLog(@"number2:%@ %@", number2, [pre evaluateWithObject:number2]? @"大于100":@"小于或等于100");
}

/** < 判断左边表达式的值是否小于右边表达式的值 */
+ (void)numberLessThan100 {
    NSNumber *number1 = @200;
    NSNumber *number2 = @99;
    NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF < 100"];
    NSLog(@"number1:%@ %@", number1, [pre evaluateWithObject:number1]? @"小于100":@"大于或等于100");
    NSLog(@"number2:%@ %@", number2, [pre evaluateWithObject:number2]? @"小于100":@"大于或等于100");
}

/** != <> 不等于 */
+ (void)numberNotEqual100 {
    NSNumber *number1 = @101;
    NSNumber *number2 = @100;
    NSPredicate *pre1 = [NSPredicate predicateWithFormat:@"SELF != 100"];
    NSPredicate *pre2 = [NSPredicate predicateWithFormat:@"SELF <> 100"];
    NSLog(@"number1:%@ %@", number1, [pre1 evaluateWithObject:number1]? @"不等于100":@"等于100");
    NSLog(@"number2:%@ %@", number2, [pre2 evaluateWithObject:number2]? @"不等于100":@"等于100");
}

/** 介于两个值之间 */
+ (void)numberBetween100T0200 {
    NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF BETWEEN {100, 200}"];
    NSNumber *number1 = @90;
    NSNumber *number2 = @102;
    NSLog(@"number1:%@ %@", number1, [pre evaluateWithObject:number1]? @"在100到200之间":@"不在100到200之间");
    NSLog(@"number2:%@ %@", number2, [pre evaluateWithObject:number2]? @"在100到200之间":@"不在100到200之间");
}


/**
 * =、==：判断两个表达式是否相等，在谓词中=和==是相同的意思都是判断，而没有赋值这一说
 * 判断内容是否为123
 */
+ (void)isEqualStringis123 {
    NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF = '123'"];
    NSString *string1 = @"123";
    NSString *string2 = @"125";
    NSLog(@"string1:%@ %@",string1, [pre evaluateWithObject:string1]? @"等于123":@"不等于123");
    NSLog(@"string2:%@ %@",string2, [pre evaluateWithObject:string2]? @"等于123":@"不等于123");
}

/** 判断是否等于10 */
+ (void)isEqual10 {
    NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF = 10"];
    NSNumber *number1 = @10;
    NSNumber *number2 = @12;
    NSLog(@"number1:%@ %@",number1, [pre evaluateWithObject:number1]?@"等于10":@"不等于10");
    NSLog(@"number2:%@ %@",number2, [pre evaluateWithObject:number2]?@"等于10":@"不等于10");
}



@end

@implementation Person

+ (instancetype)personWithName:(NSString *)name age:(NSInteger)age {
    Person *person = [[Person alloc] init];
    person.name = name;
    person.age = age;
    return person;
}


@end

